package com.shanxia.im.sdk.client.coder;


import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

import com.shanxia.codec.Decoder;
import com.shanxia.codec.ProtocolDataBase;

/**
 * 客户端消息解码
 */
public class ClientMessageDecoder {

	/**
	 *
	 * @param headerBuffer 读取到的消息头
	 * @param socketChannel
	 * @return
	 */

	public ProtocolDataBase doDecode(ByteBuffer headerBuffer , SocketChannel socketChannel) throws IOException {

		headerBuffer.position(0);

		byte h1 = headerBuffer.get();
		byte h2 = headerBuffer.get();
		byte lv = headerBuffer.get();
		byte hv = headerBuffer.get();

		headerBuffer.clear();

		/*
		 * 先通过消息头拿到消息的长度，然后进行定长读取
		 * 解决消息的断包和粘包情况
		 */
		int dataLength = getContentLength(lv, hv);

		ByteBuffer bodyBuffer = ByteBuffer.allocate(dataLength-4);

		/*
		 * 如果读取的消息长度不够，则进行等待后续消息到来
		 * 当读取的消息长度(bodyBuffer.position() == dataLength)时意味着一个完整的消息已经接收完成
		 */
		do {
			socketChannel.read(bodyBuffer);
		} while (bodyBuffer.position() != dataLength-4);

		byte[] dataBytes = new byte[dataLength-4];
		bodyBuffer.get(dataBytes);

		ProtocolDataBase protocolDataBase = Decoder.decodeData(dataBytes, dataLength-4);

		return protocolDataBase;

        /*
         消息读取完成后，通过type来解析成对应的消息体
         */
		/*if (CIMConstant.ProtobufType.S_H_RQ == type) {
			return HeartbeatRequest.getInstance();
		}

		if (CIMConstant.ProtobufType.REPLY_BODY == type) {
			ReplyBodyProto.Model bodyProto = ReplyBodyProto.Model.parseFrom(bodyBuffer.array());
			ReplyBody body = new ReplyBody();
			body.setKey(bodyProto.getKey());
			body.setTimestamp(bodyProto.getTimestamp());
			body.putAll(bodyProto.getDataMap());
			body.setCode(bodyProto.getCode());
			body.setMessage(bodyProto.getMessage());
			return body;
		}

		MessageProto.Model bodyProto = MessageProto.Model.parseFrom(bodyBuffer.array());
		Message message = new Message();
		message.setId(bodyProto.getId());
		message.setAction(bodyProto.getAction());
		message.setContent(bodyProto.getContent());
		message.setSender(bodyProto.getSender());
		message.setReceiver(bodyProto.getReceiver());
		message.setTitle(bodyProto.getTitle());
		message.setExtra(bodyProto.getExtra());
		message.setTimestamp(bodyProto.getTimestamp());
		message.setFormat(bodyProto.getFormat());
		return message;*/
	}

	/**
	 * 解析消息体长度
	 */
	private int getContentLength(byte lv, byte hv) {
		int l = (lv & 0xff);
		int h = (hv & 0xff);
		return (l | h << 8);
	}


}
